<html>
    <head>
        <title>订阅本地事件</title>
    </head>
    <body>
        <script>
             /*
                        三、订阅本地事件 Subscribing to Events

                            1、事件处理程序 ILocalEeventHander<TEvent> 

                                    服务可以实现 ILocalEeventHander<TEvent> 服务来订阅和处理本地事件。

                                        eg：  处理上面定义的 StockCountChangeEvent 事件：

                                                    using System.Threading.Tasks;
                                                    using Volo.Abp.DependencyInjection;
                                                    using Volo.Abp.EventBus;

                                                    namespace AbpDemo
                                                    {
                                                        public class MyHandler
                                                            : ILocalEventHandler<StockCountChangedEvent>,
                                                            ITransientDependency
                                                        {
                                                            // 约定用此方法名称的方法处理事件
                                                            public async Task HandleEventAsync(StockCountChangedEvent eventData)
                                                            {
                                                                //TODO: your code that does something on the event
                                                            }
                                                        }
                                                    }

                                    就是这么简单。  MyHandler 由 ABP框架自动发现，并且每当发生 StockCountChangedEvent时，都会调用 HandleEventAsync 方法。

                                    你可以注入任何服务，并在处理程序类中执行任何所需的逻辑。

                                                    1、一个或多个处理程序可以订阅同一个事件。

                                                    2、通过为每个事件类型实现 ILocalEventHandler<TEvent> 接口，单个事件处理程序可以订阅处理多个事件。

                                    如果你执行数据库操作并使用事件处理程序内的存储库，你可能需要创建一个工作单元，因为某些存储库方法需要在工作单元内工作。

                                    把事件处理方法定义为 virtual 并为该方法添加一个 [UnitOfWork]特性，或者手动使用 IUnitOfWorkManager接口创建一个工作单元。


                                    
                                    ★、处理程序类必须注册到依赖注入（DI）。上面的示例使用ITransientDependency来完成它。有关更多选项，请参阅DI文档。


                            2、[LocalEventHandlerOrder] 特性    本地事件处理执行顺序
                            
                                    [LocalEventHandlerOrder]特性可用于设置事件处理程序的执行顺序，如果你想以特定的顺序执行事件处理程序，这会很有帮助：

                                                    [LocalEventHandlerOrder(-1)] // 执行顺序
                                                    public class MyHandler
                                                        : ILocalEventHandler<StockCountChangedEvent>,
                                                        ITransientDependency
                                                    {
                                                        public async Task HandleEventAsync(StockCountChangedEvent eventData)
                                                        {
                                                            //TODO: 事件处理逻辑
                                                        }
                                                    }      
                                    默认情况下，所有事件处理程序的顺序值为0.因此，如果你想在其他事件处理程序之前执行某个事件处理程序，你可以将顺序值设置为负值。



                            3、事务 和 异常行为   Transaction & Exception Behavior

                                    事件处理程序总是在"相同的工作单元作用域"中执行，这意味着在"与发布事件的代码相同数据库事务中"。

                                    如果事件处理程序抛出异常，则工作单元(数据库事务)将回滚。

                                    因此，如果你想要隐藏异常，请在事件处理程序中使用 try/catch块。

                                    
                                    
                                    
                                    当你调用 ILocalEventBus.PublishAsync时， 事件处理程序不会立即执行。

                                    相反，它们会在当前工作单元完成之前执行 (处理程序中未处理的异常仍会回滚当前工作单元)。

                                    如果要立即执行处理程序，请将onUnitOfWorkComplete 参数设置为 false.

                                    (在实体/聚合根类中发布事件时，onUnitOfWorkComplete选项不可用（请参阅在实体/聚合根类中发布事件部分））
                     */
        </script>
    </body>
</html>